using System.Collections.Generic;
using UnityEngine;
using Voodoo.Pattern.Random;

namespace Voodoo.Meta
{
	public class LeaderboardLayoutUI
	{
		private readonly LeaderboardLayout _leaderboard;

		private readonly LeaderboardData _leaderboardData;

		private readonly RectTransform _slotParent;

		private readonly LeaderboardPlayerSlot _slotPrefab;

		private readonly List<LeaderboardPlayerSlot> _slots = new List<LeaderboardPlayerSlot>();

		private LeaderboardPlayerInfo _playerInfo;

		public LeaderboardPlayerSlot PlayerSlot { get; private set; }

		public IReadOnlyList<LeaderboardPlayerSlot> Slots => _slots;

		public LeaderboardRankLogic RankLogic { get; }

		public LeaderboardLayoutUI(LeaderboardLayout leaderboard, LeaderboardRankLogic rankLogic)
		{
			_leaderboard = leaderboard;
			RankLogic = rankLogic;
			_slotParent = _leaderboard.SlotParent;
			_slotPrefab = _leaderboard.LeaderboardData.slotPrefab;
			_leaderboardData = _leaderboard.LeaderboardData;
			CreateSlots();
			PlayerSlot.nameChanged += OnPlayerNameChanged;
		}

		~LeaderboardLayoutUI()
		{
			int i = 0;
			for (; i < _slots.Count; i++)
			{
				Object.Destroy(_slots[i].gameObject);
			}
			_slots.Clear();
			PlayerSlot.nameChanged -= OnPlayerNameChanged;
			Object.Destroy(PlayerSlot.gameObject);
		}

		public void Fill(LeaderboardPlayerInfo playerInfo)
		{
			if (playerInfo == null || string.IsNullOrEmpty(playerInfo.playerName))
			{
				string @string = NintendoPlayerPrefs.GetString("Player_Name", "Player");
				Sprite playerFlag = playerInfo?.playerFlag;
				_playerInfo = new LeaderboardPlayerInfo(@string, playerFlag);
			}
			else
			{
				_playerInfo = playerInfo;
				NintendoPlayerPrefs.SetString("Player_Name", _playerInfo.playerName);
			}
			UpdateSlots();
			FocusOnSlotIndex((PlayerSlot.Rank >= _leaderboardData.playerSlotIndex) ? 1 : 2);
		}

		public void MovePlayerSlotInLayoutTransform()
		{
			PlayerSlot.transform.SetParent(_leaderboard.transform);
			PlayerSlot.transform.SetAsLastSibling();
		}

		private void ReturnPlayerSlotToOriginalTransform()
		{
			PlayerSlot.transform.SetParent(_slotParent);
			PlayerSlot.transform.SetAsLastSibling();
		}

		public void FocusOnSlotIndex(int index)
		{
			float num = ((_slots.Count > 0) ? _slots[0].Height : 0f);
			_slotParent.anchoredPosition = new Vector2(_slotParent.anchoredPosition.x, (0f - (num + _leaderboardData.spacing)) * (float)index);
		}

		public void RefreshPlayerRank()
		{
			PlayerSlot.Refresh(RankLogic.NewRank, RankLogic.GetPlayerBackgroundsColors(), RankLogic.GetPlayerMedal());
			PlayerSlot.OnValidation();
		}

		public void MoveLastSlots()
		{
			if (RankLogic.RankUp)
			{
				MoveLowerRankedPlayerDown();
			}
			else
			{
				MoveHigherRankedPlayerUp();
			}
		}

		public void SwitchLastSlotIndex()
		{
			if (RankLogic.RankUp)
			{
				MoveLastSlotAtTheTop();
			}
			else
			{
				MoveFirstSlotAtTheBottom();
			}
		}

		private void MoveLowerRankedPlayerDown()
		{
			List<LeaderboardPlayerSlot> list = new List<LeaderboardPlayerSlot>(_slots.FindAll((LeaderboardPlayerSlot slot) => slot.Rank >= RankLogic.NewRank));
			for (int i = 0; i < list.Count; i++)
			{
				list[i].MoveSlot(_leaderboardData.spacing, -1);
				int rank = list[i].Rank + 1;
				list[i].Refresh(rank, RankLogic.GetBackgroundColorsByRank(rank), RankLogic.GetMedalByRank(rank));
			}
		}

		public void Clear()
		{
			FocusOnSlotIndex((PlayerSlot.Rank >= _leaderboardData.playerSlotIndex) ? 1 : 0);
			ReturnPlayerSlotToOriginalTransform();
		}

		private void MoveHigherRankedPlayerUp()
		{
			List<LeaderboardPlayerSlot> list = new List<LeaderboardPlayerSlot>(_slots.FindAll((LeaderboardPlayerSlot slot) => slot.Rank <= RankLogic.NewRank));
			for (int i = 0; i < list.Count; i++)
			{
				list[i].MoveSlot(_leaderboardData.spacing, 1);
				int rank = list[i].Rank - 1;
				list[i].Refresh(rank, RankLogic.GetBackgroundColorsByRank(rank), RankLogic.GetMedalByRank(rank));
			}
		}

		private void MoveLastSlotAtTheTop()
		{
			LeaderboardPlayerSlot leaderboardPlayerSlot = _slots[0];
			LeaderboardPlayerSlot leaderboardPlayerSlot2 = _slots[_slots.Count - 1];
			int num = leaderboardPlayerSlot.Rank - 1;
			if (num >= 1)
			{
				Vector2 anchoredPosition = leaderboardPlayerSlot.AnchoredPosition + new Vector2(0f, leaderboardPlayerSlot.Height + _leaderboardData.spacing);
				InitNonPlayerSlot(leaderboardPlayerSlot2, anchoredPosition, num);
				_slots.Remove(leaderboardPlayerSlot2);
				_slots.Insert(0, leaderboardPlayerSlot2);
			}
		}

		private void MoveFirstSlotAtTheBottom()
		{
			LeaderboardPlayerSlot leaderboardPlayerSlot = _slots[_slots.Count - 1];
			LeaderboardPlayerSlot leaderboardPlayerSlot2 = _slots[0];
			int num = leaderboardPlayerSlot.Rank + 1;
			if (num <= 10000)
			{
				Vector2 anchoredPosition = leaderboardPlayerSlot.AnchoredPosition - new Vector2(0f, leaderboardPlayerSlot.Height + _leaderboardData.spacing);
				InitNonPlayerSlot(leaderboardPlayerSlot2, anchoredPosition, num);
				_slots.Remove(leaderboardPlayerSlot2);
				_slots.Add(leaderboardPlayerSlot2);
			}
		}

		private LeaderboardPlayerSlot Instantiate()
		{
			return Object.Instantiate(_slotPrefab, _slotParent);
		}

		private void CreateSlots()
		{
			PlayerSlot = Instantiate();
			int slotCount = _leaderboardData.slotCount;
			for (int i = 1; i < _leaderboardData.slotCount; i++)
			{
				_slots.Add(Instantiate());
			}
			float height = PlayerSlot.Height;
			Vector2 sizeDelta = _slotParent.sizeDelta;
			float y = sizeDelta.y + (height + _leaderboardData.spacing) * (float)slotCount;
			_slotParent.sizeDelta = new Vector2(sizeDelta.x, y);
		}

		private void UpdateSlots()
		{
			float num = PlayerSlot.Height + _leaderboardData.spacing;
			int playerRank = RankLogic.PlayerRank;
			int i = 0;
			int num2 = 0;
			for (; i < _leaderboardData.slotCount; i++)
			{
				int num3 = playerRank + i;
				if (playerRank >= _leaderboardData.playerSlotIndex)
				{
					num3 -= _leaderboardData.playerSlotIndex;
				}
				_ = _slotParent.sizeDelta;
				float num4 = num * (float)i;
				Vector2 anchoredPosition = new Vector2(0f, 0f - num4);
				if (num3 == playerRank)
				{
					LeaderboardPlayerSlot playerSlot = PlayerSlot;
					InitPlayerSlot(anchoredPosition, num3);
				}
				else
				{
					LeaderboardPlayerSlot playerSlot = _slots[num2];
					InitNonPlayerSlot(playerSlot, anchoredPosition, num3);
					num2++;
				}
			}
		}

		private void InitNonPlayerSlot(LeaderboardPlayerSlot slot, Vector2 anchoredPosition, int rank)
		{
			string randomPseudo = RandomizePseudo.GetRandomPseudo(_leaderboardData.pseudoPool);
			Sprite randomFlagSprite = RandomizeFlag.GetRandomFlagSprite(_leaderboardData.flagPool);
			LeaderboardSlotInfo leaderboardSlotInfo = CreateSlotInfo(rank, isPlayer: false);
			leaderboardSlotInfo.score = 0;
			leaderboardSlotInfo.anchoredPosition = anchoredPosition;
			leaderboardSlotInfo.playerInfo = new LeaderboardPlayerInfo(randomPseudo, randomFlagSprite);
			slot.Initialize(leaderboardSlotInfo);
		}

		private void InitPlayerSlot(Vector2 anchoredPosition, int rank)
		{
			LeaderboardSlotInfo leaderboardSlotInfo = CreateSlotInfo(rank, isPlayer: true);
			leaderboardSlotInfo.score = RankLogic.PreviousScore;
			leaderboardSlotInfo.anchoredPosition = anchoredPosition;
			leaderboardSlotInfo.playerInfo = _playerInfo;
			PlayerSlot.Initialize(leaderboardSlotInfo);
		}

		private LeaderboardSlotInfo CreateSlotInfo(int rank, bool isPlayer)
		{
			LeaderboardBackgroundColors backgroundColorsByRank = RankLogic.GetBackgroundColorsByRank(rank, isPlayer);
			Sprite medalByRank = RankLogic.GetMedalByRank(rank);
			return new LeaderboardSlotInfo
			{
				rank = rank,
				showScore = isPlayer,
				medal = medalByRank,
				backgroundColors = backgroundColorsByRank
			};
		}

		private void OnPlayerNameChanged(string newName)
		{
			NintendoPlayerPrefs.SetString("Player_Name", newName);
		}
	}
}
